using Gameplay.RTS.Hud;
using Gameplay.RTS.ScriptConfig;
using System.Collections.Generic;
using com.yoozoo.gta.Extension;
using UnityEngine;
using WorldMapBase.Tile.Pool;
using Yoozoo.Extension;
using System;
using com.youzu.got.protocol;
using Yoozoo.UI.YGUI;

namespace Yoozoo.Gameplay.RTS
{
  
    public class FlyTextManager
    {
        public static FlyTextManager Instance;
        public static Transform FlyTextRoot;
        public static int  MaxShowNum = 500;
        private static Dictionary<int, WorldFlyText> flyTextUsingDic = 
            new Dictionary<int, WorldFlyText>(MaxShowNum+10);

        private static int flyTextId = 0;

        private static float flyTextScale = 1;
        
        private static Dictionary<int,WorldFlyTextPool> flyTextPool = 
            new Dictionary<int, WorldFlyTextPool>(20);

        private static FlyTextConfig _config;

#if UNITY_EDITOR
        private static float cameraDistance = 0;
#endif
        private static float marchContextLod0Scale;
        private static int playZOffSetCountTime = 6;
        private static int currentPlayZOffSetCountTime = 0;

        public static int
            Origin = 0,
            NormalAttackSelf = 82,//我被攻击的普攻飘字
            NormalAttackOther = 8,//其他人造成的普攻飘字
            NormalAttackEnemy = 81,
            PassiveAttack = 83,
            Skill = 91,//我释放的怒气技能飘字
            SkillSelf = 92,//自己收到的怒气技能颜色
            SkillHeal = 10,//治疗
            AttackCity = 11,
            SkillDamageName = 12,
            SkillBuffName = 13,
            SkillHealName = 14,
            Besiege = 1000,//夹击
            Route = 1001,//胜利
            Liansha = 1002,
            Failed = 1003,//失败
            Vanquish = 1004,
            StartWar = 1005,
            MonsterDead = 1006,

            // 抢劫货车时显示：战斗、失败、胜利
            GrabTruckBattle = 1007,
            GrabTruckDefeat = 1008,
            GrabTruckVictory = 1009,

            GrabTrainDefeat = 1010,
            GrabTrainVictory = 1011,

            SkillNewSelf = 2000,
            SkillNewOther = 2001,
            FlyTextIcon = 3000,
            Defence = 3001, //扣除城防值飘字
            Resource = 3002, //掠夺飘字

            Collect = 3003, //采集飘字
            CollectTreasure = 3004, // 挖掘宝藏飘字
            
            CarSkillSelf = 4001,
            CarSkillOther = 4002;


        public void Init()
        {
            Instance = this;
        }

        public static void OnLODLevelChange(float cameraDistance)
        {
            if (_config == null)
            {
                _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
            }
            flyTextScale = _config.ScaleSpecial;
            Vector3 localScale = new Vector3(flyTextScale, flyTextScale, flyTextScale);;
            foreach (var item in flyTextUsingDic.Values)
            {
                item.FlyText.transform.localScale = localScale;
            }
        }

        public static void AddToPool(WorldFlyText flyText, int type)
        {
            if (flyTextUsingDic.Remove(flyText.id))
            {
                if (flyTextPool.TryGetValue(type,out WorldFlyTextPool pool))
                {
                    pool.RecoverItem(flyText);
                }
            }
            else
            {
                UnityEngine.Debug.LogError($"ERROR:AddToPool type={type} id={flyText.id}");
            }
        }

        public static void Free(int allocId)
        {
            if (allocId >=0 && flyTextUsingDic.TryGetValue(allocId, out var flyText))
            {
                flyText.BackToPool();
            }
        }

        private static bool CheckCanPlayFlyText(int priority)
        {
            bool canPlayText = flyTextUsingDic.Count < RTSQualityHelper.MaxFlyTextNum || RTSQualityHelper.MaxFlyTextNum == -1;
            bool limitSelf = RTSQualityHelper.LimitSelfTroop;

            if (!canPlayText)
            {
                if (priority == 1)
                {
                    if (limitSelf)
                    {
                        return false;
                    }
                }
                else
                {
                    if (priority == 2)
                    {
                        return true;
                    }
                    return false;
                }
            }

            //if (flyTextUsingDic.Count >= RTSQualityHelper.MaxFlyTextNum && RTSQualityHelper.MaxFlyTextNum != -1)
            //{
            //    return false;
            //}
            if (flyTextUsingDic.Count >= MaxShowNum || RTSQualityHelper.IsSimpleMode)
            {
                if (priority == 0)
                {
                    return false;
                }
            }

            if (MarchManager.BattleTroopCount > RTSQualityHelper.MaxFlyTextTroopNum) //当前部队数量大于最大可飘字数量不飘字
            {
                if (priority == 0)
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// 播放飘字&技能名字 接口
        /// </summary>
        /// <param name="type"></param> 
        /// <param name="position"></param>
        /// <param name="content"></param>
        /// <param name="scale"></param>
        /// <param name="targetPosition"></param>
        /// <param name="priority">播放优先级，在飘字数量达到配置的最大数量后或者玩家开启简略模式，只播放高优先级的飘字</param>
        /// <returns></returns>
        public static int Play(int type, Vector3 position,string content, float scale,Vector3 targetPosition = default,int priority=0, FlyTextAudio audioType = FlyTextAudio.NONE,string PlayAnimName = default)
        {
            if (!CheckCanPlayFlyText(priority))
            {
                return -1;
            }
       
            int allocId = -1;
            int poolType = type;
            if (type != Besiege && 
                type != Route && 
                type != Failed && 
                type != Besiege && 
                type != StartWar && 
                type != MonsterDead && 
                type != GrabTruckBattle && 
                type != GrabTruckDefeat && 
                type != GrabTruckVictory &&
                type != GrabTrainDefeat &&
                type != GrabTrainVictory &&
                type != SkillNewSelf && 
                type != SkillNewOther && 
                type != CarSkillOther && 
                type != CarSkillSelf)
            {
                poolType = Origin;
            }

            if (flyTextPool.TryGetValue(poolType, out WorldFlyTextPool pool))
            {
                if (_config == null)
                {
                    _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
                }
                
                var flyText = pool.GetItem();
                
                allocId = flyTextId++;
                flyText.id = allocId;
                float finalScale = getFinalScale() * scale;
                if (currentPlayZOffSetCountTime < playZOffSetCountTime)
                {
                    if (flyText.m_text!=null)
                    {
                        flyText.m_text.transform.localPosition = new Vector3(flyText.m_text.transform.localPosition.x, flyText.m_text.transform.localPosition.z,- (0.01f * currentPlayZOffSetCountTime));
                    }
                    currentPlayZOffSetCountTime++;
                }
                else
                {
                    currentPlayZOffSetCountTime = 0;
                }
                flyText.Play(position,content,finalScale, targetPosition, type, audioType,PlayAnimName);
                flyTextUsingDic.Add(allocId, flyText);
            }
            return allocId;
        }


        public static int PlayRepeatText(int type, string numChar, int singleNum, float scale, string animName, List<int> intervalArray, Vector3 position, Vector3 targetPosition = default, int priority = 0)
        {
            if (!CheckCanPlayFlyText(priority))
            {
                return -1;
            }
            int allocId = -1;
            int poolType = type;
            if (type != Besiege && type != Route && type != Failed && type != Besiege)
            {
                poolType = Origin;
            }

            if (type == SkillNewSelf || type == SkillNewOther || type == CarSkillOther || type == CarSkillSelf)
            {
                poolType = type;
            }
            if (flyTextPool.TryGetValue(poolType, out WorldFlyTextPool pool))
            {
                if (_config == null)
                {
                    _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
                }
                var flyText = pool.GetItem();
                allocId = flyTextId++;
                flyText.id = allocId;
                float finalScale = getFinalScale() * scale;
                if (currentPlayZOffSetCountTime < playZOffSetCountTime)
                {
                    flyText.m_text.transform.localPosition = new Vector3(flyText.m_text.transform.localPosition.x, flyText.m_text.transform.localPosition.z, -(0.01f * currentPlayZOffSetCountTime));
                    currentPlayZOffSetCountTime++;
                }
                else
                {
                    currentPlayZOffSetCountTime = 0;
                }
                flyText.PlayRepeatText(position, numChar,singleNum, finalScale, targetPosition, type, intervalArray, animName);
                flyTextUsingDic.Add(allocId, flyText);
            }
            return allocId;
        }

        public static int PlayRepeatText2(int type, string numChar, int allNum, float scale, string animName, List<Vector2Int> intervalArray, Vector3 position, Vector3 targetPosition = default, int priority = 0)
        {
            if (!CheckCanPlayFlyText(priority))
            {
                return -1;
            }
            int allocId = -1;
            int poolType = type;
            if (type != Besiege && type != Route && type != Failed && type != Besiege)
            {
                poolType = Origin;
            }

            if (type == SkillNewSelf || type == SkillNewOther || type == CarSkillOther || type == CarSkillSelf)
            {
                poolType = type;
            }
            if (flyTextPool.TryGetValue(poolType, out WorldFlyTextPool pool))
            {
                if (_config == null)
                {
                    _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
                }
                var flyText = pool.GetItem();
                allocId = flyTextId++;
                flyText.id = allocId;
                float finalScale = getFinalScale() * scale;
                if (currentPlayZOffSetCountTime < playZOffSetCountTime)
                {
                    flyText.m_text.transform.localPosition = new Vector3(flyText.m_text.transform.localPosition.x, flyText.m_text.transform.localPosition.z, -(0.01f * currentPlayZOffSetCountTime));
                    currentPlayZOffSetCountTime++;
                }
                else
                {
                    currentPlayZOffSetCountTime = 0;
                }
                flyText.PlayRepeatText2(position, numChar,allNum, finalScale, targetPosition, type, intervalArray, animName);
                flyTextUsingDic.Add(allocId, flyText);
            }
            return allocId;
        }

        
        public static int PlaySkill(int type, int team,Vector3 position,string content,float scale,Vector3 offset = default, int priority = 0,bool isCarSkill = false, string icon = null)
        {
            if (!CheckCanPlayFlyText(priority))
            {
                return -1;
            }
            int allocId = -1;
            if (flyTextPool.TryGetValue(type, out WorldFlyTextPool pool))
            {
                if (_config == null)
                {
                    _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
                }
                
                var flyText = pool.GetItem();
                
                allocId = flyTextId++;
                flyText.id = allocId;
                float finalScale = scale;//getFinalScale(type);
                if (currentPlayZOffSetCountTime < playZOffSetCountTime)
                {
                    //flyText.m_text.transform.localPosition = new Vector3(flyText.m_text.transform.localPosition.x, flyText.m_text.transform.localPosition.z,- (0.01f * currentPlayZOffSetCountTime));
                    currentPlayZOffSetCountTime++;
                }
                else
                {
                    currentPlayZOffSetCountTime = 0;
                }
                
                var yImage = flyText.m_icon;
                if (!isCarSkill)
                {
                    if (yImage)
                    {
                        ArmyManager.Instance.ResourceManager.SetFlyTextBg(team, yImage);
                    }
                }
                else
                {
                    if (yImage)
                    {
                        // ArmyManager.Instance.ResourceManager.SetCarFlyTextBg(team, yImage);
                        ArmyManager.Instance.ResourceManager.SetCarFlyTextIcon(icon, yImage);
                    }
                }
    
                flyText.FlyText.transform.SetSiblingIndex(flyText.FlyText.transform.parent.childCount - 1);
                flyText.Play(position,content,finalScale, Vector3.zero, type);
                var trans = flyText.GetTextTransform();
                if (offset == default)
                {
                    offset = Vector3.zero;
                }
                trans.localPosition = trans.localPosition + offset;
                //flyText.GetTextTransform().SetParent(parent);
                flyTextUsingDic.Add(allocId, flyText);
            }
            return allocId;
        }

        public static int PlayFlyTextIcon(int type, Vector3 position, string content,string icon,int priority = 0)
        {
            if (!CheckCanPlayFlyText(priority))
            {
                return -1;
            }
            int allocId = -1;
            int poolType = type;
            if (flyTextPool.TryGetValue(poolType, out WorldFlyTextPool pool))
            {
                if (_config == null)
                {
                    _config = ArmyManager.Instance.ResourceManager.JsonManager.GetFlyTextConfig();
                }

                var flyText = pool.GetItem();
                allocId = flyTextId++;
                flyText.id = allocId;
                float finalScale = getFinalScale();
                if (currentPlayZOffSetCountTime < playZOffSetCountTime)
                {
                    flyText.m_text.transform.localPosition = new Vector3(flyText.m_text.transform.localPosition.x, flyText.m_text.transform.localPosition.z, -(0.01f * currentPlayZOffSetCountTime));
                    currentPlayZOffSetCountTime++;
                }
                else
                {
                    currentPlayZOffSetCountTime = 0;
                }
                var spriteRender = flyText.FlyText.GetComponentInChildren<SpriteRenderer>();
                if (spriteRender)
                {
                    ArmyManager.Instance.ResourceManager.SetFlyTextIcon(icon, spriteRender);
                }
                flyText.Play(position, content, finalScale, default, type);
                flyTextUsingDic.Add(allocId, flyText);
            }
            return allocId;
        }

        static float getFinalScale()
        {
            float process = (marchContextLod0Scale - 0.001f) / 0.004f;
            float finalScale = Mathf.Lerp(1, 1.5f, process);
            return finalScale;
        }
        public static void PreloadFlyText(GameObject prefab,int count,int type)
        {
            if (FlyTextRoot == null)
            { 
                GameObject canvasObject = new GameObject("FlyTextRoot");
                var parent = PoolCollectionManager.GetInstance("PoolCollectionManager").transform;
                canvasObject.transform.SetParent(parent);
                canvasObject.transform.SetScale(0.015f);
                canvasObject.transform.SetLocalRotationX(45);
                canvasObject.transform.SetLocalRotationY(ArmyManager.Instance.CameraRotation);
                FlyTextRoot = canvasObject.transform;
            }
           
            if (!flyTextPool.ContainsKey(type))
            {
                WorldFlyTextPool pool = new WorldFlyTextPool(count, count,prefab,type);
                pool.PreInit();
                flyTextPool.Add(type,pool);
            }
        }

        public void OnUpdate(float _marchContextLod0Scale)
        {
            marchContextLod0Scale = _marchContextLod0Scale;
        }

        public void Dispose()
        {
            var enumerator = flyTextPool.GetEnumerator();
            while (enumerator.MoveNext())
            {
                enumerator.Current.Value.Destroy();
            }
            enumerator.Dispose();
            if (FlyTextRoot && FlyTextRoot.gameObject.Valid())
            {
                GameObject.Destroy(FlyTextRoot.gameObject);
                FlyTextRoot = null;
            }
            
            flyTextPool.Clear();
            flyTextUsingDic.Clear();
        }

        /// <summary>
        /// 获取FlyText时播放的音效
        /// </summary>
        /// <param name="audioType"></param>
        /// <returns></returns>
        public string GetPlayAudioName(FlyTextAudio audioType)
        {
            switch (audioType)
            {
//                case FlyTextAudio.SFX_RTS_JUMPHIT_LOCOMOTIVE:
//                    return "sfx_rts_battle_smg_jumphit";
//                case FlyTextAudio.SFX_RTS_JUMPHIT_MELEE:
//                    return "sfx_rts_battle_sg_jumphit";
//                case FlyTextAudio.SFX_RTS_JUMPHIT_SNIPER:
//                    return "sfx_rts_battle_rf_jumphit";
//                case FlyTextAudio.SFX_RTS_JUMPHIT_THROWER:
//                    return "sfx_rts_battle_bo_jumphit";
                default:
                    return "";
            }
        }
        /// <summary>
        /// 通过士兵类型获取对应攻击音效
        /// </summary>
        /// <param name="soldierType"></param>
        /// <returns></returns>
        public FlyTextAudio GetFlyTextAudioBySoldierType(int soldierType)
        {
            switch (soldierType)
            {
                case (int)SoldierType.Gerenerde:
                    return FlyTextAudio.SFX_RTS_JUMPHIT_THROWER;
                case (int)SoldierType.Motor:
                    return FlyTextAudio.SFX_RTS_JUMPHIT_LOCOMOTIVE;
                case (int)SoldierType.Shield:
                    return FlyTextAudio.SFX_RTS_JUMPHIT_MELEE;
                case (int)SoldierType.Shooter:
                    return FlyTextAudio.SFX_RTS_JUMPHIT_SNIPER;
                default:
                    return FlyTextAudio.NONE;
            }
        }
    }
}
